<?php

namespace MathPHP\Tests\Statistics\Multivariate\PLS;

use MathPHP\LinearAlgebra\Matrix;
use MathPHP\LinearAlgebra\MatrixFactory;
use MathPHP\SampleData;
use MathPHP\Statistics\Multivariate\PLS;

class CerealScaleTrueTest extends \PHPUnit\Framework\TestCase
{
    /** @var PLS */
    private static $pls;

    /** @var Matrix */
    private static $X;

    /** @var Matrix */
    private static $Y;

    /**
     * R code for expected values:
     *   library(chemometrics)
     *   data(cereal)
     *   pls.model = pls2_nipals(cereal$X, cereal$Y, a=5, scale=TRUE)
     *
     * @throws Exception\MathException
     */
    public static function setUpBeforeClass(): void
    {
        $cereal   = new SampleData\Cereal();
        self::$X  = MatrixFactory::create($cereal->getXData());
        self::$Y  = MatrixFactory::create($cereal->getYData());

        self::$pls = new PLS(self::$X, self::$Y, 5, true);
    }

    /**
     * @test         Construction
     * @throws       Exception\MathException
     */
    public function testConstruction()
    {
        // When
        $pls = new PLS(self::$X, self::$Y, 5, true);

        // Then
        $this->assertInstanceOf(PLS::class, $pls);
    }

    /**
     * @test Construction error - row mismatch
     */
    public function testConstructionFailureXAndYRowMismatch()
    {
        // Given
        $Y = self::$Y->rowExclude(0);

        // Then
        $this->expectException(\MathPHP\Exception\BadDataException::class);

        // When
        $pls = new PLS(self::$X, $Y, 2, true);
    }

    /**
     * @test The class returns the correct values for B
     *
     * R code for expected values:
     *   pls.model$B
     */
    public function testB()
    {
        // Given
        $expected = [
            [0.0424707069, 0.01922291, -0.0099608045, -0.0246390484, 0.02306057, -0.02697744],
            [0.0385832774, 0.01614914, -0.0062902995, -0.0227350397, 0.02341202, -0.02745547],
            [0.0364120503, 0.01354773, -0.0030920415, -0.020133587, 0.02361091, -0.02770132],
            [0.0354391468, 0.01204776, -0.0011469204, -0.0178106395, 0.02346253, -0.02743984],
            [0.036031669, 0.01139083, 0.000206726, -0.015767197, 0.02354168, -0.02749393],
            [0.0380948985, 0.01176063, 0.0005425224, -0.0149185035, 0.02399636, -0.02809532],
            [0.0426980856, 0.01569193, -0.0027563096, -0.017198764, 0.02434669, -0.02856139],
            [0.0524814205, 0.02560192, -0.0120915331, -0.0242491449, 0.02459862, -0.02891174],
            [0.0663227203, 0.04256282, -0.0300506637, -0.0387513507, 0.02396341, -0.02812098],
            [0.1130840159, 0.08504567, -0.0931212385, -0.1083733388, 0.02959551, -0.03949878],
            [-0.0484467113, -0.0358201, 0.0127986841, 0.0083370029, -0.01452482, 0.01396074],
            [-0.0609139848, -0.04971552, 0.0285734313, 0.0228254672, -0.01502579, 0.01476183],
            [-0.0639778879, -0.05856773, 0.0379404218, 0.0281332879, -0.01221045, 0.01075142],
            [-0.0613144204, -0.06302223, 0.0424998608, 0.0287714841, -0.008505338, 0.005436208],
            [-0.0518147647, -0.06408869, 0.0434166149, 0.0250382285, -0.002888487, -0.002626654],
            [-0.0326098073, -0.06022222, 0.0395146671, 0.0161723212, 0.00515197, -0.01411011],
            [-0.0036567904, -0.05559908, 0.0358419592, 0.005747735, 0.01736343, -0.03136755],
            [0.0217058116, -0.05177983, 0.032865107, -0.0013307204, 0.02726596, -0.0451443],
            [0.0229111624, -0.05339373, 0.0310132411, -0.0012962145, 0.02663878, -0.04384753],
            [0.0171663558, -0.05875347, 0.0303055542, 0.0008268606, 0.02389102, -0.03899036],
            [0.01966669, -0.05119482, 0.018896012, -0.0048430991, 0.02170872, -0.03268775],
            [0.0140654092, -0.02221532, 0.0009706415, -0.0120137483, 0.01385693, -0.01671632],
            [0.010535322, -0.003627285, -0.0060423234, -0.011935296, 0.008687775, -0.00747213],
            [0.010961272, 0.003932709, -0.0071171294, -0.0100341791, 0.007322952, -0.004889809],
            [0.0124638893, 0.008596039, -0.008040955, -0.0084224507, 0.006402567, -0.003277768],
            [0.0137508177, 0.01267921, -0.0100774818, -0.0072434666, 0.004816007, -0.0008347483],
            [0.0157145169, 0.01669081, -0.0127999332, -0.0065162183, 0.00318265, 0.001624437],
            [0.0182058402, 0.02063483, -0.0158069087, -0.006369192, 0.001809936, 0.003677814],
            [0.0214296591, 0.02408225, -0.0185838687, -0.0069594836, 0.001206302, 0.004596716],
            [0.023767112, 0.02613047, -0.0206776682, -0.0075820233, 0.0008058164, 0.005178105],
            [0.0229797603, 0.02545171, -0.0210337277, -0.0071953361, 0.00008875932, 0.006153056],
            [0.0177505842, 0.02187471, -0.0193941552, -0.0055691676, -0.001294524, 0.008035667],
            [0.0111067768, 0.01780601, -0.0170519324, -0.0036202706, -0.002792021, 0.01010244],
            [0.0056193324, 0.01437137, -0.0143762161, -0.0015491993, -0.003734884, 0.01143621],
            [0.0014433131, 0.01098292, -0.010912976, 0.0005101963, -0.003694139, 0.01140126],
            [-0.0009658682, 0.007862246, -0.0071448875, 0.0018486459, -0.002499802, 0.009729503],
            [-0.00271819, 0.004466526, -0.0029141211, 0.0028047425, -0.0005751842, 0.007008302],
            [-0.0053244036, 0.00002009668, 0.0021465119, 0.004170236, 0.001436816, 0.004138812],
            [-0.009332644, -0.00568251, 0.007900804, 0.0060598075, 0.003203322, 0.001582311],
            [-0.0152812229, -0.01242535, 0.0135623073, 0.0080369906, 0.004227321, 0.00002506987],
            [-0.0231033987, -0.01876942, 0.0170397458, 0.0096353031, 0.003303912, 0.001171181],
            [-0.0321356479, -0.0234367, 0.0162742961, 0.0114199585, -0.001128461, 0.00719909],
            [-0.031857544, -0.02086623, 0.0046165996, 0.0121505454, -0.009959724, 0.01905063],
            [0.0344142458, 0.0217712, -0.0494873944, -0.0023419664, -0.02295188, 0.03168389],
            [0.0540900829, 0.02867154, -0.0351225619, -0.0092794442, -0.006106874, 0.003136351],
            [0.04584578, 0.01746976, -0.017360977, -0.0060625768, 0.001804035, -0.008452304],
            [0.036460344, 0.006232529, -0.0040015298, -0.0040311588, 0.007058878, -0.01609298],
            [0.027439001, -0.003357619, 0.0055706798, -0.0058938016, 0.01185213, -0.02310077],
            [0.0207556172, -0.008586282, 0.009688652, -0.0121937208, 0.01592161, -0.02906739],
            [0.0157994036, -0.01224079, 0.012418025, -0.0200891262, 0.02044476, -0.03561466],
            [0.0095879996, -0.01549631, 0.0143241612, -0.028126949, 0.02410488, -0.04087916],
            [0.0031835289, -0.01692899, 0.014053114, -0.0351342475, 0.02564956, -0.0430837],
            [0.0001575035, -0.01663872, 0.0125261149, -0.0405776565, 0.0265501, -0.0443448],
            [0.0004019924, -0.01251035, 0.0074355888, -0.0429053335, 0.02428883, -0.04111863],
            [0.0006625679, -0.006774399, 0.0001641066, -0.0394389983, 0.01735717, -0.03132428],
            [0.0023076336, -0.001513142, -0.005897658, -0.030634203, 0.00889008, -0.01929324],
            [0.001959778, -0.000005505417, -0.0068100374, -0.0195135071, 0.002248015, -0.00974126],
            [-0.0019227169, -0.001588161, -0.005212321, -0.0114506757, -0.002105773, -0.003463192],
            [-0.0063119507, -0.003740936, -0.003068313, -0.0050610807, -0.005341753, 0.001221099],
            [-0.009752691, -0.006116652, -0.0005934806, -0.0002372117, -0.007220133, 0.003955037],
            [-0.0130379072, -0.007241091, 0.0002701054, 0.0028346833, -0.009258931, 0.006899895],
            [-0.0151823401, -0.006052894, -0.0015116911, 0.0042142962, -0.01190283, 0.01070021],
            [-0.015388405, -0.002260015, -0.0060662801, 0.0040476838, -0.01506253, 0.01524088],
            [-0.0139662662, 0.005870783, -0.0152827558, 0.0026408233, -0.0203089, 0.02279853],
            [-0.0085620889, 0.02125926, -0.0319012333, -0.0005439297, -0.02851153, 0.03467493],
            [0.0041562462, 0.04751246, -0.0583673121, -0.0029755801, -0.04158509, 0.05380726],
            [0.0296137955, 0.08717532, -0.0949252162, 0.0030548505, -0.06176666, 0.08397508],
            [0.089396077, 0.1479714, -0.1412356123, 0.0255540318, -0.08425287, 0.1217595],
            [0.0913743204, 0.09061738, -0.0706298719, 0.0206588037, -0.02810142, 0.04689808],
            [0.0805515598, 0.05867674, -0.0376422784, 0.0053395757, 0.00008965576, 0.006950319],
            [0.0788570589, 0.05334233, -0.0326574003, -0.0051376188, 0.008607103, -0.005290012],
            [0.0781045421, 0.05534266, -0.0353980725, -0.0097402462, 0.00887196, -0.005709375],
            [0.0731337249, 0.05573402, -0.0370482225, -0.0067101221, 0.00454962, 0.0004695299],
            [0.0426868068, 0.03105637, -0.0170661024, 0.0157459702, -0.002922253, 0.01100431],
            [-0.0363039964, -0.04666242, 0.0477688973, 0.0612503357, -0.006745349, 0.01545068],
            [-0.1098800844, -0.1287163, 0.116093327, 0.0844712113, 0.005096696, -0.003092674],
            [-0.1230528136, -0.1449078, 0.1256284825, 0.0613907794, 0.0196569, -0.02454816],
            [-0.1026614709, -0.1179455, 0.0953597679, 0.0188762197, 0.02729084, -0.03566958],
            [-0.07945022, -0.0839135, 0.0593492491, -0.0136590006, 0.02647841, -0.03464704],
            [-0.0781875645, -0.06278186, 0.0301859911, -0.0335059456, 0.01661981, -0.02118479],
            [-0.1679126755, -0.08891839, 0.0184067294, -0.0273487466, -0.02553835, 0.03437434],
            [-0.1323899186, -0.05817729, 0.0081921603, 0.0204742659, -0.0501596, 0.06504298],
            [-0.0736679786, -0.02577699, -0.0029607899, 0.0232610528, -0.04120825, 0.05247609],
            [-0.0478734918, -0.006504129, -0.0153813379, 0.0171882359, -0.03861017, 0.04893342],
            [-0.0329875668, 0.007394348, -0.0272032825, 0.0084461414, -0.03761704, 0.04754185],
            [-0.0234747212, 0.01237367, -0.0314365286, 0.0013920999, -0.03390528, 0.04216221],
            [-0.0201412847, 0.0110648, -0.0305847337, -0.003820714, -0.02955858, 0.03580699],
            [-0.0249522354, 0.005368351, -0.0268959376, -0.0052250316, -0.02778983, 0.03312244],
            [-0.0382386819, -0.005362983, -0.0205800657, 0.0001827897, -0.03038198, 0.03673796],
            [-0.0627308312, -0.02042403, -0.0190438248, 0.0118356744, -0.04269793, 0.05479171],
            [-0.0702445869, -0.02566651, -0.0147615075, 0.0221659188, -0.04235345, 0.06258855],
            [-0.0316340551, -0.007312619, -0.0093762874, 0.011187637, -0.01912202, 0.03233529],
            [-0.0212362843, -0.0004395765, -0.010580644, 0.0078585216, -0.01472098, 0.02652803],
            [-0.020236053, 0.001589556, -0.0112394943, 0.0076219081, -0.01467796, 0.026614],
            [-0.0228045567, 0.001209644, -0.0107419605, 0.0085047727, -0.01557662, 0.02795328],
            [-0.0263707326, -0.001254622, -0.0083913524, 0.0100415143, -0.01584985, 0.02836159],
            [-0.0301673622, -0.005674606, -0.004023615, 0.0119963327, -0.01501031, 0.02715721],
            [-0.0341327891, -0.01201236, 0.0024419656, 0.0141551563, -0.01286609, 0.0240721],
            [-0.0381840376, -0.02050794, 0.0113002309, 0.0167081497, -0.009287901, 0.01891705],
            [-0.0420590721, -0.03222214, 0.0237904109, 0.0204801615, -0.003768743, 0.01095452],
            [-0.0451264227, -0.05191896, 0.0454147641, 0.0282162798, 0.006271009, -0.003547005],
            [-0.0461213465, -0.112963, 0.1152035585, 0.0606712549, 0.0373597, -0.04862881],
            [0.0302312647, -0.1066912, 0.1334221973, 0.072512267, 0.06157589, -0.09287192],
            [0.0384648395, -0.02566599, 0.04341297, 0.029606372, 0.02335308, -0.03874714],
            [0.0374872551, -0.01190121, 0.0280891021, 0.0229669293, 0.0158005, -0.02794205],
            [0.0366721965, -0.007135139, 0.0229437132, 0.0187498402, 0.01416193, -0.02560123],
            [0.0352597158, -0.003343914, 0.0184498924, 0.0128852695, 0.01365625, -0.02491192],
            [0.0343412444, 0.001261142, 0.0131510701, 0.0046687357, 0.01399473, -0.02542058],
            [0.0334892641, 0.004818475, 0.0097140457, -0.0038500289, 0.01586555, -0.0280348],
            [0.0305803385, 0.003528362, 0.0129822955, -0.0085920354, 0.01989784, -0.03353723],
            [0.0239332893, -0.006427991, 0.0280056301, -0.0048780718, 0.02673348, -0.04264846],
            [0.0110382441, -0.02738508, 0.0582798276, 0.0110893368, 0.03634582, -0.05478175],
            [-0.0084329158, -0.04976852, 0.0889460205, 0.0312401383, 0.04285227, -0.0610314],
            [-0.0305647241, -0.0510179, 0.0843399928, 0.0318280305, 0.03432846, -0.04576653],
            [-0.0406008177, -0.02847526, 0.0473869817, 0.0093631648, 0.01818393, -0.02128936],
            [-0.0388913916, -0.002432208, 0.0088730086, -0.020914457, 0.008012965, -0.006561879],
            [-0.0353680164, 0.01253145, -0.0146217551, -0.0465891909, 0.006128369, -0.004253771],
            [-0.0355437111, 0.01664098, -0.0243612936, -0.0639929948, 0.008202887, -0.007798533],
            [-0.0387621149, 0.0146341, -0.0267615181, -0.0762238029, 0.01165587, -0.0134141],
            [-0.0324808146, 0.01775386, -0.0327231958, -0.092460958, 0.01758818, -0.02275326],
            [-0.0175005735, 0.03858259, -0.0560821362, -0.1198980608, 0.01922385, -0.02711081],
            [0.0201438196, 0.08801335, -0.1023438014, -0.110587876, -0.009676515, 0.00914035],
            [0.0389884193, 0.06517794, -0.0640650122, -0.0226570253, -0.02417734, 0.02921108],
            [0.0373588666, 0.04003488, -0.0309850242, 0.0147659134, -0.02110795, 0.0253053],
            [0.0332859541, 0.0214153, -0.0072791171, 0.0352272272, -0.01645342, 0.01896813],
            [0.0286457109, 0.007231704, 0.0095286149, 0.0476578199, -0.01262332, 0.01365495],
            [0.0187405971, -0.005323096, 0.0223320074, 0.0538538895, -0.01003899, 0.009934844],
            [0.0060325068, -0.008282277, 0.0229140781, 0.0514884631, -0.01244689, 0.01321014],
            [-0.0076803476, -0.005612253, 0.0162739611, 0.0434506966, -0.01726364, 0.01985935],
            [-0.0177613179, -0.003813483, 0.0111011468, 0.0344622643, -0.01940306, 0.02268148],
            [-0.0275754002, 0.0004169249, 0.0040497627, 0.0248070204, -0.02237129, 0.02679732],
            [-0.0351863686, 0.005143324, -0.0022102013, 0.0168637575, -0.02493442, 0.03047075],
            [-0.0444536783, 0.009373969, -0.0087092407, 0.0097452976, -0.02859202, 0.03574437],
            [-0.0641548221, 0.01400439, -0.0164728721, 0.0042068435, -0.03711348, 0.0482117],
            [-0.0821886374, 0.01903146, -0.0208441145, -0.0032516444, -0.04134829, 0.05522189],
            [-0.0829733769, 0.03283739, -0.0283615851, -0.0204651512, -0.03620886, 0.05053272],
            [-0.0276211156, 0.02148702, -0.0008368395, -0.0307624152, 0.007754776, -0.009293935],
            [0.0093997413, 0.001353133, 0.0294720358, -0.026018022, 0.0387182, -0.05259773],
            [0.023393017, -0.005950795, 0.0429679183, -0.0180893313, 0.04819917, -0.06635605],
            [0.0213445152, -0.01320515, 0.0510478548, -0.013563783, 0.05018468, -0.07022645],
            [-0.005011296, -0.01802805, 0.0496889452, -0.0080537364, 0.03698175, -0.05311701],
            [-0.0340241027, -0.01352357, 0.0339782771, -0.0029462209, 0.01284482, -0.02082797],
            [-0.0549823591, -0.004994418, 0.0123338641, 0.0026259519, -0.01279174, 0.01416522],
            [-0.0539707672, 0.001712832, -0.0012024957, -0.0011475047, -0.02034081, 0.02422243],
            [-0.0485038805, 0.001567452, -0.0035707154, -0.0052990628, -0.01825681, 0.02087559],
        ];

        // When
        $B = self::$pls->getCoefficients()->getMatrix();

        // Then
        $this->assertEqualsWithDelta($expected, $B, .00001, '');
    }

    /**
     * @test The class returns the correct values for C
     *
     * R code for expected values:
     *   pls.model$C
     */
    public function testC()
    {
        // Given
        $expected = [
            [0.034970929,  0.02335423,  0.29614554,  0.152681650,  0.38391867],
            [0.033493121, -0.04624945,  0.36657446,  0.208617731, -0.04463526],
            [-0.006399525, -0.06849268, -0.21305926, -0.299013879,  0.13964463],
            [-0.056663579,  0.12247338,  0.08342433, -0.303325431,  0.03359633],
            [0.078737844, -0.09124596, -0.10004379, -0.003850354,  0.20090709],
            [-0.044316572,  0.15062065,  0.14929142, -0.001252483, -0.28604875],
        ];

        // When
        $C = self::$pls->getYLoadings()->getMatrix();

        // Then
        $this->assertEqualsWithDelta($expected, $C, .00001, '');
    }

    /**
     * @test The class returns the correct values for P
     *
     * R code for expected values:
     *   pls.model$P
     */
    public function testP()
    {
        // Given
        $expected = [
            [0.0992040802128719, 0.0175169315990683, -0.00368609082549821, 0.0678862227493041, 0.0429826214560223],
            [0.0994789908681079, 0.0126334069040223, -0.00302102953194769, 0.0598135774616556, 0.0386039934197516],
            [0.0996181430279033, 0.0114755863168975, -0.00159035670572437, 0.051897058753634, 0.0368531356550849],
            [0.0997856229465998, 0.0120877098203948, -5.84581358747202E-06, 0.0444981484111191, 0.0371285398350467],
            [0.0999044411632043, 0.0130841218250602, 0.00259336656502905, 0.0381024351454788, 0.0405098745240475],
            [0.099957010924901, 0.0138599486793264, 0.00475664659459478, 0.0350091355812049, 0.0449533323815944],
            [0.0999961757413108, 0.0127753060958239, 0.00827206327467718, 0.0404763540854705, 0.050588440612615],
            [0.0998069400371328, 0.0105146839777763, 0.0140416044403674, 0.0596127992705518, 0.0584905346881834],
            [0.0987998549775193, 0.00845747995774396, 0.0168053935215267, 0.100952792229477, 0.0649462545673195],
            [0.0632948632368426, 0.0391268804698904, -0.0705386432620803, 0.344417952908091, 0.132245751513308],
            [-0.0979093069904922, 0.0161462684188173, -0.0845228344425596, 0.00791254017230576, -0.0210919801308482],
            [-0.0984829586639293, 0.0140578128612875, -0.0804236514157914, -0.0383186737317052, -0.0265209253199219],
            [-0.098085799265676, 0.016344433370583, -0.0876277359916066, -0.0532299717983064, -0.0189333776622916],
            [-0.097601734731188, 0.0202921768434296, -0.0969465079790037, -0.0530442564862894, -0.0048816036171401],
            [-0.0966448562626742, 0.0270229467467926, -0.110639977557762, -0.0385742977918871, 0.0216753147378882],
            [-0.0945812173144778, 0.0379996040304582, -0.127661092978582, -0.00773557410579715, 0.0629640424877999],
            [-0.0895729959197809, 0.0565848606967648, -0.147608565091223, 0.0326717769315477, 0.126492001331655],
            [-0.0821435047586659, 0.0780853264758587, -0.16399523248901, 0.0663602135215488, 0.178984370509484],
            [-0.0737077317379362, 0.101913507898126, -0.178470710567188, 0.078127194404385, 0.186076231462211],
            [-0.0555774992807362, 0.138465510893226, -0.198986315519869, 0.086636876418434, 0.177876241052563],
            [-0.00138322756267333, 0.18099824308317, -0.204756255797873, 0.114499578205474, 0.151426166269217],
            [0.0682597812757973, 0.140895152425784, -0.127315147076518, 0.0965603093934513, 0.0686699190481135],
            [0.0901135225053138, 0.0893931161473094, -0.058730839393289, 0.0633765210816737, 0.0178977916390915],
            [0.0957242405175184, 0.0638559611283342, -0.0253081305682729, 0.0439085482793468, -0.000105237576511182],
            [0.0976022658113161, 0.0511666163786322, -0.00537994731076922, 0.0334632382390663, -0.00753681658075525],
            [0.0983264217766552, 0.0451933011399693, 0.0086745499992697, 0.0264541952652998, -0.012455371918861],
            [0.0985960600314419, 0.042859407443765, 0.0196918800065649, 0.0216865571294474, -0.0144583960024139],
            [0.0986775779310267, 0.0418884243355726, 0.0286316691416775, 0.0197557878426953, -0.0145643008085335],
            [0.0986652103060019, 0.0418565625656468, 0.0344518495699606, 0.0208919745367377, -0.0120019467149732],
            [0.0984873509639263, 0.0440446307996124, 0.0363415891728962, 0.0229969493332334, -0.0083558893432168],
            [0.0980803721240475, 0.0487701650598923, 0.0333821014985463, 0.0241366623450512, -0.0078453268198133],
            [0.0975741789959551, 0.0541694754248513, 0.0266000905015957, 0.0221747713759864, -0.0132276903303142],
            [0.0973154191480245, 0.0570327891305633, 0.020452997284268, 0.017290878465275, -0.0207808763357649],
            [0.0974344716167281, 0.0567247308351193, 0.0172052518026695, 0.00982200313965617, -0.026536683455842],
            [0.0978344175646095, 0.0539043960562391, 0.0151520446003969, 0.00125251878822201, -0.0295026623181517],
            [0.0984005752833609, 0.049192833277775, 0.012731512597441, -0.00611493433990428, -0.0293680020361278],
            [0.0989937467530713, 0.0435153400470417, 0.00904062626421908, -0.0134009117841597, -0.026882471150348],
            [0.0994244690524324, 0.0383779781764836, 0.00367258835388068, -0.021523369966645, -0.0238739637252691],
            [0.0996006043152467, 0.0350186873552784, -0.00403769750669514, -0.0300026786648375, -0.0218427063155471],
            [0.0994393276268004, 0.0348409439761649, -0.0153907816003318, -0.037129740174576, -0.0225921558569011],
            [0.0986734942457482, 0.0404616064314705, -0.0298167732654973, -0.0409795334464056, -0.027526971524805],
            [0.0962077642599412, 0.0577093560038072, -0.0460107633426179, -0.0399608618489473, -0.0364174182539314],
            [0.0859181547766947, 0.10168320737004, -0.0640373118119722, -0.0225946243887349, -0.0364437264991814],
            [-0.0137877282586336, 0.180313403559484, -0.0626447403842185, 0.0703899039169264, 0.0473851483274428],
            [-0.0940494415939746, 0.0467213213246375, -0.00034228890950549, 0.0653256386582816, 0.0815730238986131],
            [-0.0991239093158933, 0.00415476032184281, 0.00588039533215051, 0.0456011601725205, 0.0806867342019973],
            [-0.0996916714248211, -0.0171283873708152, -0.00240703137868334, 0.0354451078460404, 0.0765689166619442],
            [-0.0990413868416344, -0.0335429598126617, -0.0192050998958805, 0.0365239963064396, 0.071251708135712],
            [-0.0974002025560444, -0.0485082555876611, -0.0383516016000906, 0.0499437689903379, 0.064920452720782],
            [-0.0945761963164032, -0.0647321348261047, -0.057888722593133, 0.0658919231256475, 0.0610639466817269],
            [-0.0909740280610433, -0.0801932888032083, -0.076798186731665, 0.0808401852791239, 0.0555412347828004],
            [-0.0875542079467927, -0.0919019143126399, -0.0910775340327034, 0.0946376201887425, 0.0456867100658356],
            [-0.0849739859213477, -0.0989593832284746, -0.100965556207362, 0.105945015848539, 0.0388133904726305],
            [-0.0850212356664232, -0.0978169510896634, -0.0997844229747439, 0.112970369132626, 0.0321448023378643],
            [-0.0889760454473576, -0.083520262941257, -0.0864507639770703, 0.111987022239121, 0.0204707929649284],
            [-0.0942275767182267, -0.0615655279440143, -0.0631225017907029, 0.0983512108372251, 0.0115892087474946],
            [-0.0976527325748575, -0.0451220687047965, -0.0391877069679016, 0.0728588579087151, 0.00769101908993053],
            [-0.09916056758477, -0.0359764506453468, -0.0262296267467592, 0.0511928471457641, 0.00433679535596138],
            [-0.0998921410833977, -0.0302553795629029, -0.0168788050792092, 0.0338883695905592, 0.000920899718706748],
            [-0.100242881278866, -0.0271691478309662, -0.0118462431123827, 0.0193237380812493, -0.000521912431283796],
            [-0.100426251064434, -0.0251142126963349, -0.00869712831239283, 0.00997948593785282, -0.00533744715222818],
            [-0.100585032176817, -0.0223578023954962, -0.00517329755765382, 0.00754409144227552, -0.0135711686729542],
            [-0.10072144128758, -0.0185277523282056, -0.00015911286155602, 0.0112045738808901, -0.0232036553026369],
            [-0.100781683225672, -0.0126218051725223, 0.01003117143646, 0.0188112213965095, -0.0372530057549435],
            [-0.100481725752459, -0.00297568519301942, 0.0295942241286475, 0.032237293947545, -0.0541435926954427],
            [-0.0986790743404438, 0.0149213334214128, 0.071317998813322, 0.0475418717966423, -0.0730257942091094],
            [-0.0900049337047071, 0.0535582978463157, 0.152031517039691, 0.0461150437135369, -0.088893957378199],
            [-0.0257330241020807, 0.140481307438471, 0.301010941533141, 0.00536228177776126, -0.0709944446119616],
            [0.0733493008462701, 0.105814606093348, 0.200839241082119, -0.0249316057303495, 0.0368348551965873],
            [0.0917454586162861, 0.0619248928506288, 0.123180903753137, -0.0046106113423352, 0.0745887122167296],
            [0.095731511843692, 0.0430363461176972, 0.0979422853002138, 0.0162811972812563, 0.083432415516634],
            [0.0964623952772297, 0.0377028001891473, 0.0941697697468939, 0.0267440583885972, 0.0800354402497849],
            [0.0958645947041664, 0.0431240109898191, 0.0993746580921856, 0.0208949342028422, 0.0685037133925317],
            [0.093598996112475, 0.0648941144385541, 0.0877476042898242, -0.0346139837212016, 0.0436836409940829],
            [0.085061585138083, 0.0985219320281648, 0.00896578832647743, -0.150294010270524, -0.0024212789943432],
            [0.0758048506832178, 0.1008054435718, -0.117351594892713, -0.214959159625338, -0.0318230280170406],
            [0.0796574666480938, 0.07466002342577, -0.192507874903557, -0.159733903430423, -0.0339201876117417],
            [0.0854422229700479, 0.0447972899936123, -0.220558637643537, -0.0519422468370921, -0.0366144201423415],
            [0.0869021582503183, 0.0296258125137123, -0.219289536069745, 0.0387189021950749, -0.0541828074060102],
            [0.0814408923718011, 0.0359742851539756, -0.230357156998313, 0.106272603798883, -0.112087803497571],
            [0.022949123063856, 0.0926901137725606, -0.322263360860121, 0.131358156203072, -0.309395647084145],
            [-0.0829444682089755, 0.0741704011951128, -0.13916679190271, 0.00254990308673939, -0.234358674569285],
            [-0.09609423405635, 0.0445625990085922, -0.0439531038350487, -0.0182426153085313, -0.134100730991487],
            [-0.0985485295834908, 0.03283863506072, -0.00909609046413048, -0.00771387744634898, -0.0994904344796219],
            [-0.0992989275448911, 0.0263637893306308, 0.00334692496125707, 0.013786734468484, -0.0847969622099351],
            [-0.0996449478165388, 0.0224125690289483, -0.00012878516836382, 0.034380683737399, -0.0695545619223693],
            [-0.099796478271403, 0.0191174312412253, -0.0129154298118459, 0.0487373876875709, -0.0562962612748862],
            [-0.0997035280012149, 0.0198550298372058, -0.0286651433287201, 0.0526147632298947, -0.0544485557240044],
            [-0.0985661785112702, 0.0357408075579744, -0.0441120627069496, 0.0469361497554798, -0.0644687150547525],
            [-0.0861295107368461, 0.102273551553604, -0.0757741607901515, 0.0475590139852272, -0.10129676906163],
            [0.0481044612698184, 0.182572813830247, -0.0796393780773168, 0.0160132317786063, -0.12599652199549],
            [0.0866048975347811, 0.109084686325567, -0.0277569241543331, -0.00256796939933421, -0.0717943498910745],
            [0.0917000502713262, 0.0897631508374095, -0.0115798420592565, -0.00554206940743403, -0.0586181464616826],
            [0.0930234397400269, 0.0835979435919794, -0.0051307771844205, -0.0112398655721644, -0.0565944317462291],
            [0.0935511165094663, 0.0805756566720159, -0.0032717013326896, -0.0185795636135207, -0.0584400300634413],
            [0.0938539253651958, 0.0783589144250295, -0.00482034660774514, -0.0272323490370578, -0.0590937790478513],
            [0.0941178206026093, 0.0760574538223887, -0.00960497628958546, -0.0369197787252229, -0.05716502556508],
            [0.0944750993927813, 0.0727733833845791, -0.0175043429846071, -0.0473948579762118, -0.0523245845478372],
            [0.0948162359946145, 0.0686829563826061, -0.028664542321389, -0.059217103224637, -0.0440060956933159],
            [0.0948610339772416, 0.0646933737102632, -0.0436463439196547, -0.0736707308113141, -0.0296619495000669],
            [0.0938364273242448, 0.0624725985151312, -0.0661631516762472, -0.0965078921905291, -0.000605911010404064],
            [0.0840134469336659, 0.0675979093914783, -0.119819435325736, -0.177207273716567, 0.101382431457452],
            [-0.0877835776542487, -0.00733587119341067, -0.0518026751744559, -0.158290247725137, 0.240855277478374],
            [-0.0979867739584704, -0.0288429755370183, 0.0238527449136849, -0.0481144273609671, 0.119963929182269],
            [-0.0983139715793247, -0.0340986020644542, 0.037939606802341, -0.0325397545804325, 0.0925967505564579],
            [-0.0979604590474857, -0.0411936240758001, 0.0400624487720188, -0.0245506205264286, 0.0810778641794959],
            [-0.0972574082304345, -0.0505341164162316, 0.0373673570971363, -0.0138754759716993, 0.0724105785296717],
            [-0.0958405345917601, -0.06305845950429, 0.0330395827367946, 0.00290491749791571, 0.0633888298396435],
            [-0.0930501287395441, -0.080201566631573, 0.0271590285177697, 0.0169997603804325, 0.0553864045877996],
            [-0.0879262143931545, -0.102659863852067, 0.0220329912644141, 0.0155466689241321, 0.0519683203065928],
            [-0.0784390900146579, -0.130325541119601, 0.0199199406979847, -0.0177331351480094, 0.0597522109677558],
            [-0.0568572309343428, -0.163242673269269, 0.0238294118438751, -0.0998675864258084, 0.0758385660088351],
            [-0.0123715980093065, -0.181643914234347, 0.0294721129347228, -0.198634407413725, 0.0769918555355978],
            [0.0402343547963779, -0.157685051197661, 0.0186558740032239, -0.218338124219122, 0.0329468489182062],
            [0.0711961285031437, -0.120690378909754, -3.31863474019937E-05, -0.148725377366278, -0.0235587651664634],
            [0.0834550920784936, -0.100539225373515, -0.023519883924901, -0.0543829991139962, -0.0639739640399727],
            [0.0858702650699986, -0.0956758745668262, -0.0535777099890416, 0.0264303244636332, -0.0828496532017105],
            [0.0838081212263931, -0.0988193657243024, -0.0835452033460358, 0.0825846879579102, -0.0865686718372828],
            [0.079381705501856, -0.104751921033365, -0.114005428116928, 0.123568158198739, -0.0834477373244998],
            [0.0716498288640978, -0.114594571323622, -0.141604997588338, 0.177337061999993, -0.0786647081557462],
            [0.0450821386601423, -0.142360333666837, -0.154321339464538, 0.269028381899761, -0.0967799537955116],
            [-0.0523662633471229, -0.125057970939494, -0.0388493315592808, 0.299693129027861, -0.128678460629194],
            [-0.0943262852648248, -0.0306398552523123, 0.0889060949787988, 0.0963965017401904, -0.0490749848045617],
            [-0.096860951140645, -0.0061609176709756, 0.117475399505344, -0.0023742571617378, -0.00686304063722916],
            [-0.0963603587378384, -0.00131400984777991, 0.125016616312867, -0.061413628758058, 0.0147078213519722],
            [-0.0957302909547862, 0.00058594738522854, 0.123176150320692, -0.0990398723271464, 0.0303601228724955],
            [-0.0955185905302033, -0.00399806753294742, 0.112485973058999, -0.121262493812842, 0.0261295850994009],
            [-0.0957509413883506, -0.0148187036888129, 0.102900779847695, -0.12440968297448, 0.00655981472870277],
            [-0.0958553569309889, -0.028890471616639, 0.093955275949501, -0.113326073282887, -0.019290811080924],
            [-0.0957243567981411, -0.0426016181858032, 0.0831148417370284, -0.0951112371713887, -0.0381682374518832],
            [-0.0943652771670088, -0.0592837531605503, 0.075893067876406, -0.0744485433803163, -0.0663307484827041],
            [-0.0917535452927007, -0.0752146525639846, 0.0720366227232356, -0.0556918306192469, -0.100422310565474],
            [-0.0887214617455406, -0.0880984470204748, 0.0692548226936466, -0.042319576716352, -0.129539848376207],
            [-0.0820394009789414, -0.105781431725851, 0.0728670757368544, -0.0358002677245242, -0.188432101072312],
            [-0.0652627322487983, -0.140898716847219, 0.0815259378477541, -0.0395651483539125, -0.246828852867176],
            [-0.0223057267481334, -0.190789493065393, 0.0978123539365141, -0.05431257356806, -0.24910556721895],
            [0.0260929438924495, -0.200812971119449, 0.0677357583028691, -0.0617930124745238, -0.0635709306803582],
            [0.0408320038876941, -0.190578426709276, 0.0346910915891226, -0.0744920093812687, 0.0704540910142455],
            [0.0341499170781504, -0.193927491606166, 0.0352509508411518, -0.0988277273761126, 0.109777304558284],
            [0.0170579133656864, -0.20222186419699, 0.0303141928486888, -0.116931994477874, 0.116183838249184],
            [-0.00970556289473895, -0.207268625364472, 0.0279711552330142, -0.122621179474802, 0.0530590462939857],
            [-0.0435769836156114, -0.188348536943488, 0.0374157871399357, -0.0921592146968402, -0.0576971339917401],
            [-0.0694912528262793, -0.142888234979314, 0.0540231096461223, -0.0607599975177819, -0.137666777609936],
            [-0.0794259831786336, -0.112817887769036, 0.0530099354184012, -0.027224474791687, -0.149805130340899],
            [-0.0829197703238874, -0.0994308792879423, 0.0403881472288224, -0.00143464231532142, -0.137120986541818],
        ];

        // When
        $P = self::$pls->getProjection()->getMatrix();

        // Then
        $this->assertEqualsWithDelta($expected, $P, .00001, '');
    }

    /**
     * @test The class returns the correct values for T
     *
     * R code for expected values:
     *   pls.model$T
     */
    public function testT()
    {
        // Given
        $expected = [
            [-4.06593619167225, 6.6203379736542, 1.90947728135645, 0.816140477797108, -0.38938979267237],
            [-5.14316228319451, 7.03069145518895, 1.24174109615413, 1.63420395136693, -0.0600539179630575],
            [-4.69589481260757, 1.88871874945902, 3.04125841097661, 0.602791501621304, -2.69206590908342],
            [12.165771623886, -5.17578992590144, 1.12484413853668, 1.3310430950722, 0.178962352087752],
            [9.87028070115601, -1.91443465764029, -1.77262228932264, 2.93151375705409, 1.12795605151355],
            [14.5196479621103, -2.99001886998375, 2.74981519793169, 1.23234406692092, 0.543517188225819],
            [-12.9433455855315, -3.87980510588052, -2.20900164014808, 1.24899914412761, -0.308516828290459],
            [-6.95885925780322, -1.08335029697545, -0.868314160101845, 0.158704279002772, -0.934400462220777],
            [-10.8926071798405, -5.86397109450444, -2.03143190794586, -0.265348898842661, -0.851871704080918],
            [4.36357641133715, 4.33873247018924, -3.88487228313518, -0.697582021773524, -0.264443536177775],
            [9.59457369219492, 4.69201088447444, -1.68803528635079, -2.25424796154897, -0.894218067375713],
            [-4.08594629983543, -6.38691298100201, 0.445986526638971, -1.06200728390051, -0.00621521064696775],
            [-15.1670467801415, 3.09625900387048, 0.899596745317251, -0.407149498475916, 3.50820405299004],
            [1.14402501553982, -3.32599794189915, 2.56807511807446, -4.02280749757958, 0.48527366936923],
            [12.2949229844023, 2.95353033695071, -1.52651694798185, -1.2465971108418, 0.557262114325042],
        ];

        // When
        $T = self::$pls->getXScores()->getMatrix();

        // Then
        $this->assertEqualsWithDelta($expected, $T, .00001, '');
    }

    /**
     * @test The class returns the correct values for U
     *
     * R code for expected values:
     *   pls.model$U
     */
    public function testU()
    {
        // Given
        $expected = [
            [-0.192772440207888, 0.518474582753274, 0.886387842293001, 0.178844655401133, -0.960718563102159],
            [-0.156882048588066, 0.521329444736645, 0.996713388448852, 0.233335659909258, -0.38748388075046],
            [-0.143051178267827, 0.505805004674239, 1.18688107404484, 0.45641265157492, -0.957771309904509],
            [0.32629569097911, -0.417506979922744, 0.60069268853441, 1.16490707621077, 0.635213131134472],
            [0.36053721264588, -0.564013997778873, 0.127103251144599, 1.04380531796491, 0.968794209249644],
            [0.300652392941888, -0.489596077230899, 0.58930838834251, 0.70324946749832, 0.954058732041379],
            [-0.113708550195695, 0.00229533250420268, -0.875092374199316, -0.0765534077783051, -0.678425918283541],
            [-0.140682309230516, 0.0558240718037661, -0.291079136124134, -0.427492520990968, -0.382878587222888],
            [-0.0742273628718169, -0.0776956261551118, -0.660547416127124, -0.5305871755095, -0.198666736578443],
            [-0.0489095135805016, -0.124576071892217, -1.49437172721319, -0.657728493253991, -0.150760370139912],
            [-0.0754841994848035, 0.0381613914266345, -0.594349496136974, -0.738047172687521, 0.0334741502570088],
            [0.0582942508259115, -0.303382547694717, -0.755475024956738, -0.482968360083706, 0.156748856676658],
            [-0.146320323268755, 0.340942984783518, 0.34930988456038, -0.604197118365785, 0.399262994020741],
            [0.0204947138872569, -0.02277674164239, 0.151208974763014, -0.331718225164554, 0.395683821275236],
            [0.0257636644158254, 0.0167152296346727, -0.216690317374135, 0.0687376452750096, 0.173469471326779],
        ];

        // When
        $U = self::$pls->getYScores()->getMatrix();

        // Then
        $this->assertEqualsWithDelta($expected, $U, .00001, '');
    }

    /**
     * @test The class returns the correct values for W
     *
     * R code for expected values:
     *   pls.model$W
     */
    public function testW()
    {
        // Given
        $expected = [
            [0.100556117453725, 0.00283977613085331, 0.0107640769532387, 0.0507394428480378, 0.064604668096711],
            [0.101774831776127, -0.0015896268701678, 0.0077050582262302, 0.0415781649574108, 0.0610889096662486],
            [0.101781142770601, -0.00224346840980808, 0.00594851234064765, 0.0327322062227642, 0.0605593688063896],
            [0.101333824975438, -0.000771479758967914, 0.00576434486794939, 0.0260257579573787, 0.0607437699585791],
            [0.100911868158016, 0.00106406798795383, 0.00712306654567306, 0.0205504119169463, 0.0630719454783557],
            [0.100860281848538, 0.00226719015561121, 0.00924033078358708, 0.0186918284359671, 0.0671245173283131],
            [0.101984706625472, 0.00148504838639813, 0.0152572337621783, 0.0254025213422821, 0.0708740853606683],
            [0.104354923568411, -0.000906003745567385, 0.0282038689712954, 0.0462617141080892, 0.076194454654885],
            [0.107443520551251, -0.00478164510168322, 0.0459836232195545, 0.0900227991877201, 0.0787384743640308],
            [0.0815503242790571, -0.0100669481556951, 0.0359748698514906, 0.33177965110527, 0.119946717893091],
            [-0.105827457837762, 0.00675950295832893, -0.0782499230683154, 0.0164318252087935, -0.0446207745134313],
            [-0.109507585835239, 0.00919129819952368, -0.0885588416812679, -0.0285579245042827, -0.0497211026073572],
            [-0.110669742758813, 0.0102955409475326, -0.100716471791706, -0.0432550749681095, -0.0407388231682803],
            [-0.110966274115757, 0.0113908726324102, -0.109754748964999, -0.0424578232427873, -0.0258856289876937],
            [-0.110306197728543, 0.0131351050912844, -0.117524367726843, -0.0262287530318022, -0.000630027118581278],
            [-0.107946649114855, 0.0164192567334888, -0.121644876262916, 0.00838633940798742, 0.0389618698773868],
            [-0.103324163377013, 0.0237194395346927, -0.126464317899926, 0.0517660843246586, 0.100417300142936],
            [-0.0985799050772271, 0.0361305939817212, -0.129571643030227, 0.0856882737902586, 0.154136824349962],
            [-0.097651579884725, 0.056922556044705, -0.138879886564536, 0.0968931831866617, 0.159297271090196],
            [-0.0919258085129328, 0.0898617673290869, -0.157434897338596, 0.104980518710136, 0.15411990237607],
            [-0.0508694529850969, 0.128370725037439, -0.158973462622847, 0.12637266773336, 0.143448609826182],
            [0.0287994600473762, 0.105422289459623, -0.0970130420228959, 0.0962538763669939, 0.0732918788043209],
            [0.0647261741409088, 0.0695880636687667, -0.0441399814858601, 0.055880389323535, 0.0290847640082993],
            [0.0774677219004949, 0.0514013044346402, -0.0184163661102239, 0.0324013268232419, 0.0154874093875352],
            [0.0828765469181546, 0.0430516129945172, -0.00256789452562533, 0.0191729082804715, 0.0099744613999972],
            [0.0851033323726697, 0.0406097014835998, 0.0094826761382749, 0.011872386399893, 0.00500977517998987],
            [0.0859320287936264, 0.0412001278299063, 0.0198263963633512, 0.00842856586171859, 0.00179989548831057],
            [0.0863143655974303, 0.042507438478844, 0.028928069986171, 0.00767130500993911, 5.64479865019976E-05],
            [0.0865665440535056, 0.0437200493194376, 0.0358266339861421, 0.00980163481219188, 0.00114247333852581],
            [0.0859568233748635, 0.0462949815606301, 0.0389912415284917, 0.0133601828327763, 0.00279201375181356],
            [0.0839504624358402, 0.0506619113295754, 0.0366941975599201, 0.0151236902006378, 0.00206122105530387],
            [0.0810697481652026, 0.055507009106623, 0.0291466895059776, 0.0131455448496954, -0.00387167813562051],
            [0.0789922769411628, 0.0583946990728986, 0.0214131402092065, 0.00855310598663778, -0.012239171179868],
            [0.0783283923432536, 0.0588317885882401, 0.0161842978269992, 0.00179327598374292, -0.0190357232663647],
            [0.0788630574530501, 0.05683940917578, 0.0119210437241763, -0.006330298619766, -0.0227282172425385],
            [0.0804529701682905, 0.0525457355344853, 0.00799293263257112, -0.013235896630049, -0.0225501160655733],
            [0.08249636964599, 0.0469754450603184, 0.00327815563528346, -0.0194048620705335, -0.0201781759169243],
            [0.0840742868795619, 0.0417175652082953, -0.00335624293444688, -0.0264699226788075, -0.0178764535852515],
            [0.0846481003392033, 0.0379017185783026, -0.0125907545899777, -0.0340950693949172, -0.0166020605202585],
            [0.0837000034133027, 0.0367350559801385, -0.025063955525418, -0.0401791531995663, -0.0180249774335316],
            [0.0801683997293467, 0.0411506935058023, -0.0391265782519096, -0.0416993833499731, -0.0247741131612543],
            [0.0711181412817758, 0.0572895827824571, -0.0527124865860086, -0.0365571824168113, -0.0379522692223292],
            [0.047054019151049, 0.0996110351474272, -0.0583250025323227, -0.00864984040569497, -0.0431806679342169],
            [-0.066362774786956, 0.172509390664261, -0.00101890228119216, 0.124133830789425, 0.036217201291886],
            [-0.0997312436012998, 0.0414212763340954, 0.0419521716544927, 0.0952715552484146, 0.0772108497869124],
            [-0.0924234419303656, -0.00130767713289619, 0.0331108581127437, 0.0612177187309137, 0.080054226842018],
            [-0.0873018013798755, -0.0247407574484674, 0.0166119309453565, 0.0417903351483767, 0.0797376920071874],
            [-0.081863526918464, -0.04514348867733, -0.0032622632742052, 0.0366135381702056, 0.0775580434696195],
            [-0.0751121541336768, -0.0650000587418478, -0.0202799776294076, 0.0453948034168795, 0.0731371985575951],
            [-0.0665134680395557, -0.0860552215412963, -0.0357168266598784, 0.0581651702088245, 0.07002774481305],
            [-0.0573887676597037, -0.106060209038261, -0.050916771083679, 0.0712969580502904, 0.0631061882567562],
            [-0.0498065900894222, -0.120903193680792, -0.0618546374888406, 0.0834745700943719, 0.0519010600708043],
            [-0.0445001863252861, -0.129792855618808, -0.0677042642811141, 0.0945236672777849, 0.0450675357967674],
            [-0.0446956236771911, -0.127668956577064, -0.0627066892216767, 0.102223325429213, 0.0379452119350642],
            [-0.0536929760899951, -0.109706619316183, -0.0494287189432004, 0.101173535101403, 0.0265848897231407],
            [-0.0670636926335584, -0.0819320541792708, -0.031322847800769, 0.0891961644285989, 0.0184341349805498],
            [-0.0775513672263703, -0.0591471857954886, -0.016713245556901, 0.0664489232873402, 0.0125188192619631],
            [-0.0836191197505133, -0.0458716164502572, -0.01165349245429, 0.0477139823751985, 0.00478549562116014],
            [-0.0875758226695666, -0.0370439330331168, -0.00933300471019081, 0.0316469701247157, -0.00271114146797125],
            [-0.0900998791547221, -0.0314274618292351, -0.00898461888928691, 0.0190328928403666, -0.00720010716347718],
            [-0.0919200084489607, -0.0272053580541263, -0.00820563578172346, 0.0109957679460028, -0.0134452238734052],
            [-0.0935602832089073, -0.0226516266045449, -0.00488218634438248, 0.00829930952115421, -0.0211971118294273],
            [-0.0951197451753856, -0.0171360603323877, 0.00179822285274216, 0.0109092053120328, -0.0291539942116661],
            [-0.0971200255606474, -0.00831132960485467, 0.0155341641453068, 0.0184936246592936, -0.0415251456107614],
            [-0.0995505261110499, 0.0063739016085584, 0.0416245376603605, 0.0337582832636379, -0.0583384161971698],
            [-0.102924481583814, 0.0340049325003903, 0.0907051377713639, 0.0514841588127714, -0.079220034027583],
            [-0.106866479623617, 0.0922259952308591, 0.176670943685277, 0.0548208279905425, -0.0979408428808023],
            [-0.0713789930932247, 0.213674019083201, 0.324420402412159, 0.0206460252212024, -0.0815784593773887],
            [0.0408607157145229, 0.14942731451546, 0.208291345979279, -0.0181097499835693, 0.033353917071622],
            [0.0758976201246673, 0.083159986571099, 0.129684676087362, -0.00494012749066979, 0.0728034198448695],
            [0.0876891555941165, 0.0561770129823599, 0.108435923045668, 0.0137851304036921, 0.081247675556247],
            [0.0906498410594181, 0.04958189776943, 0.107375761882982, 0.0240252605139008, 0.0764175770814798],
            [0.0872217018116523, 0.0574655472217595, 0.110230299068361, 0.017671281074498, 0.063129315927774],
            [0.0720858555622231, 0.0830323222241765, 0.0793673438357565, -0.0388262514160747, 0.0341499602888019],
            [0.0406945331704347, 0.111600546408188, -0.0413973116307324, -0.159517170625354, -0.0114924489020388],
            [0.0231722806973324, 0.0933117076453888, -0.19369220657839, -0.230801693293645, -0.0311634189463924],
            [0.0388467829703447, 0.0464598150095408, -0.255538476022496, -0.179857693335949, -0.0267096461169663],
            [0.0621781089906219, 0.0035073009338497, -0.248013168807561, -0.0704369318125618, -0.0228467432784232],
            [0.0747427995570043, -0.0161905803818296, -0.214898843230037, 0.0192904832958735, -0.0279043359968151],
            [0.0698852092455762, -0.012324061109044, -0.200264943120365, 0.0836589305332776, -0.0627581978637736],
            [-0.0149536985386836, 0.0410966676449561, -0.277782227754468, 0.109531310646234, -0.227068435852899],
            [-0.119691369006858, 0.0658347644289165, -0.136497006378956, -0.00250314894157628, -0.205917177353995],
            [-0.11921277217789, 0.0499141329788231, -0.0470524840388622, -0.0170940698854763, -0.127802631486507],
            [-0.115116006338354, 0.0423484162182021, -0.00789038738005414, -0.00219754485253215, -0.102259003439277],
            [-0.111489507147538, 0.0366186276809761, 0.0129420399689472, 0.0220919220903368, -0.0920969642148626],
            [-0.108483644987046, 0.0296331747361681, 0.0160153694168073, 0.0420467628550213, -0.0777409202887381],
            [-0.106160414784827, 0.021991919848012, 0.00725870163488508, 0.0563207815636791, -0.0662472973386505],
            [-0.106278258200239, 0.0191919850370232, -0.00769152716159257, 0.0605338191644184, -0.0664343421559279],
            [-0.111742264862342, 0.0320963763749746, -0.0286382443507578, 0.0513335675318563, -0.0786098879515446],
            [-0.123750925696007, 0.093844066671254, -0.0646485663884636, 0.0473592894674975, -0.111828728198184],
            [-0.0196255214549795, 0.176012093421891, -0.0811135321816889, 0.0144251441953792, -0.127937839726929],
            [0.0459602909168909, 0.109021792537784, -0.0318921909828508, -0.00489640568095562, -0.0690163885744957],
            [0.058260114189872, 0.0923692374529449, -0.0154135641515771, -0.00673161603850249, -0.0566943906823817],
            [0.0614069918426876, 0.0884350609193434, -0.00988480571765496, -0.00965747630946969, -0.0581408952074739],
            [0.0622783256593007, 0.087280465258328, -0.00927795600713094, -0.0141318377957294, -0.0636689681606164],
            [0.0625788221885745, 0.0861896949033945, -0.0124834206179055, -0.0200890350119948, -0.0676372602400678],
            [0.0628695107675603, 0.0842000207811459, -0.0192103289047318, -0.0272893313374964, -0.0684052556858808],
            [0.0635881382413174, 0.0803837073773912, -0.0294368287050418, -0.0356498933025967, -0.0658460268212695],
            [0.0645915370801801, 0.0748115846320372, -0.0434123241427809, -0.045620163523957, -0.0593232289285134],
            [0.0653052941750297, 0.0680199137043087, -0.0623383482637364, -0.059066854369172, -0.046283533651845],
            [0.0644258111032065, 0.0601097101489851, -0.0925399130305823, -0.0829268762903711, -0.0163772398097255],
            [0.051400606303597, 0.0485182595971968, -0.17533820917108, -0.17296608151984, 0.0952719139809131],
            [-0.084752689397553, -0.0368823945632574, -0.112301352805948, -0.187755409487264, 0.272063458288136],
            [-0.0848316653657822, -0.037460035003461, 0.00275849709525676, -0.0686273122655847, 0.141596268455639],
            [-0.0835353939056074, -0.0377391968272632, 0.0231539132340362, -0.0518189896040995, 0.113611823096312],
            [-0.080769466054176, -0.043457090981307, 0.0287115606894589, -0.0433812232027653, 0.10320425426306],
            [-0.0766572623803512, -0.0526929805266533, 0.0303608825053935, -0.0314624189835143, 0.0935845133327175],
            [-0.0703307695829792, -0.0661591136807278, 0.031366699923943, -0.0147272222763904, 0.0840109223411187],
            [-0.0611733695204123, -0.0841850275564954, 0.0308907125174617, -2.39368690066733E-05, 0.0767455603045676],
            [-0.0487463094621366, -0.106352972417994, 0.026569175521617, -0.000411581822296046, 0.0734136423114382],
            [-0.0320386623039182, -0.130737264824421, 0.016608253565569, -0.0303177794164997, 0.0765689032924058],
            [-0.00461524949568679, -0.154308398776413, 0.000881829533322387, -0.103431258935685, 0.0838172080069597],
            [0.0390686331522324, -0.1598973773913, -0.0167491543029971, -0.188963626788535, 0.0762152802158198],
            [0.0797020313928547, -0.129730291860094, -0.0287354202799091, -0.196258239537015, 0.0230274179008436],
            [0.0997848551561873, -0.0954112963981426, -0.0244496974786433, -0.12019805344227, -0.0432326673071781],
            [0.109576263213262, -0.083093227391702, -0.0175063711884803, -0.0231347706028819, -0.0857898673596498],
            [0.114636310161541, -0.0888811443691444, -0.0229657321776674, 0.0551093985611356, -0.102419027909524],
            [0.116531851716856, -0.102232746167879, -0.037998639832219, 0.105370954676575, -0.107752489726041],
            [0.115975133294514, -0.117623035071258, -0.0583623989938196, 0.139280315032968, -0.109152907942057],
            [0.114821466502064, -0.138025223380454, -0.0710514321342404, 0.18509329355232, -0.096917849637092],
            [0.102227077897343, -0.174756382414502, -0.0564286317188158, 0.260948956177124, -0.0954011604915877],
            [0.00175804502266308, -0.141268030783694, 0.062761050256778, 0.27715706713314, -0.100069542806021],
            [-0.0784900545842219, -0.01955266565141, 0.118905276200889, 0.0840466918168609, -0.0258418713791044],
            [-0.0929836920137974, 0.0124181048224655, 0.112893704649245, -0.0129322328237732, 0.0125555474286674],
            [-0.0967864259650775, 0.0204444043552448, 0.100989028131119, -0.071511178507821, 0.0355744676369886],
            [-0.0986057814744826, 0.0234412125588133, 0.0875432538650224, -0.107782090538893, 0.0499803966851781],
            [-0.0983911390812646, 0.0180933159417258, 0.0694801197803674, -0.129812838340067, 0.0498164658228518],
            [-0.0964977283517779, 0.00796728614553491, 0.0603370172881146, -0.129913616843373, 0.0258002293472305],
            [-0.0930234393627048, -0.00535985175837766, 0.0555829728538347, -0.115202172671455, -0.0105870311271867],
            [-0.0886250059761867, -0.0203543139066418, 0.0482598390510168, -0.0972175119206216, -0.0364260598107845],
            [-0.0821184333406974, -0.0370561136995896, 0.0459323331838234, -0.0794660740405885, -0.0662314062555782],
            [-0.0746914058498549, -0.0525959448458647, 0.0474586508557921, -0.0669290056316411, -0.0920524315922135],
            [-0.067959833237038, -0.064431236881152, 0.0479281878905213, -0.0552648483774776, -0.121121143144725],
            [-0.0576625595668436, -0.0775304363147188, 0.0510447476525746, -0.0538571815364901, -0.176236983782005],
            [-0.0318897958806215, -0.106385876647669, 0.0570423779750653, -0.0597625686077189, -0.227761981573259],
            [0.0267278803448987, -0.148013614362954, 0.0737388432592358, -0.0504079497213247, -0.254151209234309],
            [0.0860807961150451, -0.174322194321447, 0.0472209160842896, -0.0334996837009247, -0.0992414044616511],
            [0.101995657074303, -0.178252023114388, 0.0153989645676249, -0.0411084118104958, 0.0271583646187386],
            [0.0968555306492183, -0.181983411669866, 0.0143123925315508, -0.0619076953064134, 0.073903039120903],
            [0.0819548090552544, -0.190425088193278, 0.00695188799136602, -0.0738923774841092, 0.0831815075701705],
            [0.0536464560649576, -0.192435003407001, 0.00154045211005107, -0.0878444399899295, 0.0296558981638071],
            [0.0111018763978619, -0.171573893340342, 0.00938717903602102, -0.0871058035170633, -0.0485900707437779],
            [-0.0305214763820871, -0.124871222156949, 0.0207773293139912, -0.0742873012328177, -0.116437918068103],
            [-0.0477917169781452, -0.100356249937238, 0.0225559352690923, -0.0441660016218717, -0.126778866094592],
            [-0.0533637223242243, -0.0942742251762942, 0.0143042061970816, -0.0232174415699909, -0.11284729132428],
        ];

        // When
        $W = self::$pls->getXLoadings()->getMatrix();

        // Then
        $this->assertEqualsWithDelta($expected, $W, .00001, '');
    }

    /**
     * R code for expected values:
     * X = cereal$X[1,]
     * (X - colMeans(cereal$X)) %*% solve(diag(apply(cereal$X, 2, sd))) %*% pls.model$B %*% diag(apply(cereal$Y, 2, sd)) + colMeans(cereal$Y)
     *
     * @test         predict Y values from X
     * @dataProvider dataProviderForRegression
     * @param        array $X
     * @param        array $Y
     */
    public function testRegression($X, $expected)
    {
        // Given.
        $input = MatrixFactory::create($X);

        // When
        $actual = self::$pls->predict($input)->getMatrix();

        // Then
        $this->assertEqualsWithDelta($expected, $actual, .00001, '');
    }

    public function dataProviderForRegression()
    {
        $cereal   = new SampleData\Cereal();
        return [
            [
                [$cereal->getXData()[0]],
                [[18477.0390263222, 41.5281149343885, 6.57031011991723, 1.90026547049335, 60.2644668311084, 2.29765285930859]],
            ],
            [
                [$cereal->getXData()[9]],
                [[18213.1527906436, 40.5422275834801, 6.81637687565496, 1.63361755716235, 68.5844929048772, 1.67599676584021]],
            ]
        ];
    }

    /**
     * @test predict error if the input X columns do not match
     */
    public function testPredictDataColumnMisMatch()
    {
        // Given
        $X = MatrixFactory::create([[6, 160, 3.9, 2.62, 16.46]]);

        // Then
        $this->expectException(\MathPHP\Exception\BadDataException::class);

        // When
        $prediction = self::$pls->predict($X);
    }
}
